package org.cloud.automatic.queue.listener;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.cloud.automatic.queue.config.SystemSendQueueConfig;
import org.cloud.automatic.queue.entity.SystemSendQueueBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * 补偿队列线程帮助类，用于获取当前线程的补偿点信息
 */

@Slf4j
@Component
public class SystemSendQueueHelper {
	
    private static ThreadLocal<SystemSendQueueBO> local = new ThreadLocal();
    private static ThreadLocal<String> localBusinessCode = new ThreadLocal();
    private static ThreadLocal<Boolean> finishQueueFlag = new ThreadLocal();
    private static SystemSendQueueConfig config;
    private static ThreadLocal<String> localFailedReason = new ThreadLocal();

    @Autowired
    private SystemSendQueueConfig systemSendQueueConfig;

    @PostConstruct
    public void init() {
        SystemSendQueueHelper.config = systemSendQueueConfig;
    }


    /**
     * 设置当前线程的补偿点
     *
     * @param bo
     */
    public static void setSystemSendQueueBO(SystemSendQueueBO bo) {
        SystemSendQueueHelper.local.set(bo);
    }

    /**
     * 获取当前线程的补偿点
     *
     * @return
     */
    public static SystemSendQueueBO getSystemSendQueueBO() {
        return SystemSendQueueHelper.local.get();
    }

    /**
     * 设置当前补偿点的业务明细流水号
     *
     * @param businessCode
     */
    public static void setBusinessCode(String businessCode) {
        SystemSendQueueHelper.localBusinessCode.set(businessCode);
    }

    /**
     * 获取当前补偿点业务的业务流水号
     *
     * @return String
     */
    public static String getBusinessCode() {
        return SystemSendQueueHelper.localBusinessCode.get();
    }
    
    /**
     * 设置当前失败原因.
     * @param failedReason
     */
    public static void setFailedReason(String failedReason) {
    	SystemSendQueueHelper.localFailedReason.set(failedReason);
    }
    
    /**
     * 获取当前失败原因.
     * @return
     */
    public static String getFailedReason() {
    	return SystemSendQueueHelper.localFailedReason.get();
    }


    /**
     * <pre>
     * 标记当前补偿点需要被终止。
     * 当补偿点业务处理失败，并且将业务状态改为失败这个操作成功以后，调用这个方法通知补偿点将当前补偿点终止。
     * </pre>
     */
    public static void finishCurrentQueue() {
        SystemSendQueueHelper.finishQueueFlag.set(Boolean.TRUE);
    }


    /**
     * 判断当前补偿点的业务状态是否应设置为失败
     *
     * @return Boolean Type. return true if current business status can be fail.
     */
    public static boolean currentBusinessCanBeFailed() {
    	if (getSystemSendQueueBO().getSendNum() != null) {
    	    log.info("当前补偿对象数据：{}", JSON.toJSONString(getSystemSendQueueBO()));
    		log.info("当前补偿点流水号：{}", getSystemSendQueueBO().getBizCode());
    		log.info("当前补偿点发送次数：{}", getSystemSendQueueBO().getSendNum());
    		log.info("当前补偿点最大发送次数：{}", config.getMaxFailTimes());
    	}
    	
        return (getSystemSendQueueBO().getSendNum() >= config.getMaxFailTimes());
    }

    /**
     * 判断是否终止当前补偿点(状态设置为完成)
     *
     * @return Boolean Type. return true if current queue can be finished.
     */
    public static boolean isFinishedCurrentQueue() {
        Boolean flag = SystemSendQueueHelper.finishQueueFlag.get();
        if (flag == null) {
            flag = Boolean.FALSE;
        }
        return flag;
    }

    /**
     * 移除当前线程补偿点
     */
    public static void remove() {
        SystemSendQueueHelper.local.remove();
        SystemSendQueueHelper.localBusinessCode.remove();
        SystemSendQueueHelper.finishQueueFlag.remove();
        SystemSendQueueHelper.localFailedReason.remove();
    }


}
